﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Google.GData.Client;
using BLL;
using Google.GData.Documents;
using System.Text.RegularExpressions;
using Logic;
using System.Configuration;
using Google.GData.Calendar;
using Google.GData.Extensions;

namespace ClarizenGadget.Controllers
{
    public class GoogleController : Controller
    {
        OAuthParameters parameters;

        public ActionResult Oauth()
        {
            ClearSession();
            var url = GetAuthorizeUrl();
            Session["secret"] = parameters.TokenSecret;
            Session["token"] = parameters.Token;
            Session["verifier"] = parameters.Verifier;

            return Redirect(url);
        }

        public ActionResult Callback()
        {
            try
            {
                parameters = GetParams();
                ClearSession();
                OAuthUtil.UpdateOAuthParametersFromCallback(Request.QueryString.ToString(), parameters);

                OAuthUtil.GetAccessToken(parameters);

                // If you want to extract the OAuth Token/TokenSecret from the OAuthParameters instance:
                string accessToken = parameters.Token;
                Console.WriteLine("OAuth Access Token: " + accessToken);

                string accessTokenSecret = parameters.TokenSecret;
                Console.WriteLine("OAuth Access Token's Secret: " + accessTokenSecret);

                var user = Users.GetCurrentUser();
                user.GoogleOauthToken = accessToken;
                user.GoogleOauthSecret = accessTokenSecret;
                user.Update();
                ViewBag.Success = true;
            }
            catch // i  was unable to cach the denied differently
            {
                ViewBag.Success = false;
            }
            return View();
        }

        public String GetAuthorizeUrl()
        {
            GetParams();
            OAuthUtil.GetUnauthorizedRequestToken(parameters);
            return OAuthUtil.CreateUserAuthorizationUrl(parameters);
        }

        private OAuthParameters GetParams()
        {
            // Multi-scoped token.
            string SCOPE = "https://docs.google.com/feeds/ https://www.google.com/calendar/feeds/";

            parameters = new OAuthParameters()
            {
                ConsumerKey = ConfigurationManager.AppSettings["GmailToken"],
                ConsumerSecret = ConfigurationManager.AppSettings["GmailSecret"],
                Scope = SCOPE,
                Callback = Logic.Constants.CurrentUrl + "/Google/Callback",
                SignatureMethod = "HMAC-SHA1",
                TokenSecret = Session["secret"] as String,
                Token = Session["token"] as String,
                Verifier = Session["verifier"] as String
            };

            return parameters;
        }

        private OAuthParameters GetLoggedInParams()
        {
            var user = Users.GetCurrentUser();
            return new OAuthParameters()
            {
                ConsumerKey = ConfigurationManager.AppSettings["GmailToken"],
                ConsumerSecret = ConfigurationManager.AppSettings["GmailSecret"],
                SignatureMethod = "HMAC-SHA1",
                TokenSecret = user.GoogleOauthSecret,
                Token = user.GoogleOauthToken
            };
        }

        private void ClearSession()
        {
            Session.Remove("secret");
            Session.Remove("token");
            Session.Remove("verifier");
        }

        public ActionResult Documents(String url = "https://docs.google.com/feeds/default/private/full/folder%3Aroot/contents?v=3&showroot=true")
        {
            try
            {
                OAuthParameters parameters = GetLoggedInParams();
                var APPLICATION_NAME = "Clarizen-Gadget-1";

                GOAuthRequestFactory requestFactory = new GOAuthRequestFactory("Docs", APPLICATION_NAME, parameters);

                DocumentsService service = new DocumentsService(APPLICATION_NAME);
                service.RequestFactory = requestFactory;

                DocumentsListQuery query = new DocumentsListQuery(url);
                DocumentsFeed feed = service.Query(query);
                foreach (DocumentEntry entry in feed.Entries)
                {
                    Console.WriteLine(entry.Title.Text);
                }

                var folderFormat = "<a class='link', href='{1}' target='_blank'>{0}</a>";
                var fileFormat = @"<input type='radio' name='cbFiles' class='cbFiles'/>
                                    <a class='link' target='_blank' href='{1}'>{0}</a>";

                var res = feed.Entries.Select(e => 
                {
                    var isFolder = new Regex(".*folder.*").IsMatch(e.Id.Uri.ToString());
                    return new
                    {
                        text = String.Format(isFolder? folderFormat: fileFormat, e.Title.Text, e.AlternateUri.Content),
                        hasChildren = isFolder,
                        id =  e.AlternateUri.Content // online//e.Content.Src.Content, //download
                        //link = e.AlternateUri.Content // online
                    };
                });

                return Json(new GadgetResponse<Object>
                {
                    Status = GadgetResponseStatus.Success,
                    Data = res,
                    NoEncoding = true
                });

                
                 
            }
            catch
            {
                return Json(false);
            }
        }

        public ActionResult Calendar()
        {
            try
            {
                //DeleteCalendar("Little League Schedule");
                //CreateNewCalendar();

                CreateEvents();

                //CalendarService service = GetCalendarService();

                //var feedUrl = "https://www.google.com/calendar/feeds/lehmannds@gmail.com/private/full";


                //EventQuery myQuery = new EventQuery(feedUrl);
                //myQuery.StartTime = new DateTime(2007, 1, 5);
                //myQuery.EndTime = new DateTime(2012, 1, 7);

                //EventFeed myResultsFeed = service.Query(myQuery);


                return null;
            }
            catch
            {
                return Json(false);
            }
        }

        private CalendarService GetCalendarService()
        {
            OAuthParameters parameters = GetLoggedInParams();
            var APPLICATION_NAME = "Clarizen-Gadget-1";

            GOAuthRequestFactory requestFactory = new GOAuthRequestFactory("Calendar", APPLICATION_NAME, parameters);

            CalendarService service = new CalendarService(APPLICATION_NAME);
            service.RequestFactory = requestFactory;

            return service;
        }

        private void CreateNewCalendar()
        {
            CalendarService service = GetCalendarService();

            CalendarEntry calendar = new CalendarEntry();
            calendar.Title.Text = "Little League Schedule";
            calendar.Summary.Text = "This calendar contains the practice schedule and game times.";
            calendar.TimeZone = "America/Los_Angeles";
            calendar.Hidden = false;
            calendar.Color = "#2952A3";
            calendar.Location = new Where("", "", "Oakland");

            Uri postUri = new Uri("https://www.google.com/calendar/feeds/default/owncalendars/full");
            CalendarEntry createdCalendar = (CalendarEntry)service.Insert(postUri, calendar);
        }

        private void DeleteCalendar(string title)
        {
            CalendarService service = GetCalendarService();

            CalendarQuery query = new CalendarQuery();
            query.Uri = new Uri("https://www.google.com/calendar/feeds/default/owncalendars/full");
            CalendarFeed resultFeed = (CalendarFeed)service.Query(query);

            foreach (CalendarEntry entry in resultFeed.Entries)
            {
                if (entry.Title.Text == title)
                    entry.Delete();
            }
        }

        private void CreateEvents()
        {
            CalendarService service = GetCalendarService();

            // Get some events to operate on.
            var feedUrl = "https://www.google.com/calendar/feeds/lehmannds@gmail.com/private/full";
            EventQuery myQuery = new EventQuery(feedUrl);
            EventFeed feed = service.Query(myQuery);

            // Add the entries to a new feed.
            AtomFeed batchFeed = new AtomFeed(feed);

             //Create an batch entry to insert a new event.
            for (int i = 0; i < 28; i++)
            {
                EventEntry toCreate = new EventEntry("new event " + i);
                toCreate.Times.Add(new When(DateTime.Today.AddDays(i), DateTime.Today.AddDays(i).AddHours(6)));
                toCreate.BatchData = new GDataBatchEntryData("D" + i, GDataBatchOperationType.insert);
                batchFeed.Entries.Add(toCreate);
            }

            EventFeed batchResultFeed = (EventFeed)service.Batch(batchFeed, new Uri(feed.Batch));


            //check the return values of the batch operations to make sure they all worked.
            //the insert operation should return a 201 and the rest should return 200
            bool success = true;
            foreach (EventEntry entry in batchResultFeed.Entries)
            {
                if (entry.BatchData.Status.Code != 200 && entry.BatchData.Status.Code != 201)
                {
                    success = false;
                    Console.WriteLine("The batch operation with ID " +
                        entry.BatchData.Id + " failed.");
                }
            }
        }
    }
}
